<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>JS 原型与原型链终极详解</title>
</head>
<body>
</body>
<script type="text/javascript">

	// for(var x=0; x<5; x++){

	// }

	(function tt(){
		console.log(6666);
	})();


	// var my = "3.14159"
	// str = ""+my
	// i_int = ~~my
	// f_float = 1*my
	// b_bool = !!my
	// arry = [my]
	// throw {
	// 	name: "什么错误？",
	// 	message: 'Add zifuchuan'
	// }

	// console.log('my='+my+'='+(typeof my))
	// console.log('str='+str+'='+(typeof str))
	// console.log('i_int='+i_int+'='+(typeof i_int))
	// console.log('f_float='+f_float+'='+(typeof f_float))
	// console.log('b_bool='+b_bool+'='+(typeof b_bool))
	// console.log('arry='+arry+'='+(typeof arry))


	// var animal = function(){};
 // var dog = function(){};


 // animal.price = 2000;
 // // animal.prototype.price = 3000
 // dog.prototype = animal;
 // Function.prototype.price = 6666
 // // dog.__proto__ = {
 // // 	price:4444444
 // // };
 // Function.prototype = {
 // 	price:333333
 // }
 // var tidy = new dog();
 // console.log(animal)
 // console.log(dog.__proto__) //undefined
 // console.log(Function.prototype) //undefined
 // console.log(dog.price) //undefined
 // console.log(dog.price) //undefined
 // console.log(tidy.price) // 2000


// var f1 = function(){}
// function F(){}
// F.prototype = function(){
// 	hah:'dgfd'
// }
// var f2 = new F()

// var f3 = new f2()

// console.log(f2.__proto__)
// console.log(F.prototype)
// console.log(f2.constructor.prototype)
// console.log(f2.constructor.prototype==F.prototype)
// console.log(F.prototype)

/*
对象

普通对象
函数对象

构造函数
实例

constructor
prototype
__proto__


	一、普通对象与函数对象
		javascript中，万物皆对象。
	二、构造函数和实例
		function Person(){}
		var person = new Person();
		1.实例的构造函数属性（constructor）指向构造函数。
	三、函数对象都有一个prototype属性，指向函数的原型对象。
	
	【定律一】：每个对象都有__proto__属性，但只有函数对象才有prototype属性
				__proto__属性用于指向创建它的构造函数的原型对象
	四、原型对象
		1.原型对象就是 Person.prototype 
		2.默认情况下，所有的原型对象都会自动获得一个 constructor（构造函数）
			这个属性是指向 prototype 属性所在的函数（Person）
			Person.prototype.constructor == Person
			person1.constructor == Person

	【结论二】：原型对象（Person.prototype）是 构造函数（Person）的一个实例。

		Person.prototype.constructor == Person;
		person1.__proto__ == Person.prototype;
		person1.constructor == Person;

	五、构造器
		var obj = {} 等同于 var obj = new Object()

		obj 是构造函数（Object）的一个实例。所以：

		obj.constructor === Object
		obj.__proto__ === Object.prototype
	
	新对象 obj 是使用 new 操作符后跟一个构造函数来创建的。
	构造函数（Object）本身就是一个函数（就是上面说的函数对象），
	它和上面的构造函数 Person 差不多。
	只不过该函数是出于创建新对象的目的而定义的。

	同理，可以创建对象的构造器不仅仅有 Object，
	也可以是 Array，Date，Function等。
	所以我们也可以构造函数来创建 Array、 Date、Function

	var b = new Array();
	b.constructor === Array;
	b.__proto__ === Array.prototype;
	这些构造器都是函数对象：

	【特例】【Object.prototype 对象也有proto属性，但它比较特殊，为 null 。
	因为 null 处于原型链的顶端，这个只能记住。
	Object.prototype.__proto__ === null】

	七、函数对象
		1.所有的函数对像的__proto__都指向Function.prototype,他是一个空函数（Empty function）

		Number.__proto__ === Function.prototype  // true
		Number.constructor == Function //true

	【Function.prototype也是唯一一个typeof XXX.prototype为 function的prototype】
	【其它的构造器的prototype都是一个对象】

	console.log(typeof Function.prototype) // function
	console.log(typeof Object.prototype)   // object
	console.log(typeof Number.prototype)   // object

	【结论】：所有构造器（含内置及自定义）的__proto__都是Function.prototype

	Function.prototype.__proto__ === Object.prototype

	Object.prototype.__proto__ === null

	八、Prototype

		在 ECMAScript 核心所定义的全部属性中，最耐人寻味的就要数 prototype 属性了。
		对于 ECMAScript 中的引用类型而言，prototype 是保存着它们所有实例方法的真正所在。
		换句话所说，诸如 toString()和 valuseOf() 等方法实际上都保存在 prototype 名下，
		只不过是通过各自对象的实例访问罢了。

	console.log(Object.prototype)
	所以我可以用 Person.constructor 也可以用 Person.hasOwnProperty。

	我们可以用一个 ES5 提供的新方法：Object.getOwnPropertyNames
	获取所有（包括不可枚举的属性）的属性名不包括 prototy 中的属性，
	返回一个数组：

	作者：Yi罐可乐
	链接：http://www.jianshu.com/p/dee9f8b14771
	
*/

function Person(name){
	this.name = name;
}

Person.prototype = {
	hetname: function(){}
}

var p = new Person("jwk");

console.log(p.__proto__)
console.log(typeof p.constructor)
console.log(p.constructor.prototype)
console.log(Person.prototype)
console.log(typeof p.constructor)

// var dog = function(){};
// Function.prototype.price = "6666";
//  dog.prototype.price = 2000;
//  var tidy = new dog();
//  console.log(tidy.price); // 2000
//  console.log(dog.price); //undefined


// console.log(pp.__proto__.constructor)
// console.log(Q.prototype)
// console.log(Function.prototype.toString())
// console.log(typeof P.prototype)
// console.log(typeof p.__proto__)
// console.log(Object.prototype)


/*
	原型
	this：始终指向调用它的对象


*/

/*
	今天讲解下JS的原型和原型链， 要想彻底弄清楚原型链，我们必须先要了解几个概念。

	1.对象：javascript中，万物皆对象！
	2.普通对象 和函数对象
		2.1 什么是函数对象：带关键词 function的  
		function f1(){}
		var f2 = function(){}
		var f3 = new Function('str','console.log(str)');
	3.构造函数
		function Person(name,age,job){
			this.name = name;
			this.age = age;
			this.job = job;
			this.sayname = function(){alert(this.name)}
		}
		var p1 = new Person('zake',28,'soft engin')
	4.
*/

</script>
</html>